const DATA_URL = 'recipes.json';

const FACETS = [
  { key: 'constitution', label: '体质' },
  { key: 'season', label: '季节' },
  { key: 'stage', label: '术后阶段' },
  { key: 'stimulus', label: '刺激强度' },
  { key: 'digestibility', label: '易消化' },
];

let RECIPES = [];
let state = {
  q: '',
  filters: {
    constitution: new Set(),
    season: new Set(),
    stage: new Set(),
    stimulus: new Set(),
    digestibility: new Set(),
  },
  theme: 'light',
};

function normalize(str) { return (str || '').toString().trim().toLowerCase(); }
function contains(text, q) { if (!q) return true; return normalize(text).includes(normalize(q)); }
function escapeRegExp(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }

function highlight(text, q) {
  if (!q || !text) return text || '';
  const re = new RegExp(escapeRegExp(q), 'gi');
  return String(text).replace(re, m => `<mark class="highlight">${m}</mark>`);
}

function debounce(fn, wait = 200) {
  let t; return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), wait); };
}

function matchesFilters(recipe) {
  for (const key of ['constitution','season','stage']) {
    const selected = state.filters[key];
    if (selected.size > 0) {
      const vals = new Set(recipe[key] || []);
      let ok = false; for (const s of selected) { if (vals.has(s)) { ok = true; break; } }
      if (!ok) return false;
    }
  }
  const stimSel = state.filters.stimulus; if (stimSel.size > 0 && !stimSel.has(recipe.stimulus)) return false;
  const digSel = state.filters.digestibility; if (digSel.size > 0) { const val = recipe.digestibility ? '是' : '否'; if (!digSel.has(val)) return false; }
  return true;
}

function matchesQuery(recipe, q) {
  if (!q) return true;
  const fields = [
    recipe.name,
    recipe.alias && recipe.alias.join('、'),
    recipe.functions,
    recipe.indications,
    recipe.method,
    recipe.dosage,
    recipe.caution,
    recipe.tags && recipe.tags.join('、'),
    (recipe.constitution || []).join('、'),
  ].filter(Boolean).join('\n');
  return contains(fields, q);
}

function buildFilters(recipes) {
  const filtersEl = document.getElementById('filters');
  const activeEl = document.getElementById('activeFilters');
  filtersEl.innerHTML = ''; activeEl.innerHTML = '';
  const options = { constitution: new Set(), season: new Set(), stage: new Set(), stimulus: new Set(), digestibility: new Set() };
  for (const r of recipes) {
    (r.constitution || []).forEach(v => options.constitution.add(v));
    (r.season || []).forEach(v => options.season.add(v));
    (r.stage || []).forEach(v => options.stage.add(v));
    if (r.stimulus) options.stimulus.add(r.stimulus);
    if (typeof r.digestibility === 'boolean') options.digestibility.add(r.digestibility ? '是' : '否');
  }
  for (const facet of FACETS) {
    const card = document.createElement('div'); card.className = 'filter-card';
    const title = document.createElement('h3'); title.textContent = facet.label; card.appendChild(title);
    const opts = Array.from(options[facet.key]).sort(); if (opts.length === 0) continue;
    for (const opt of opts) {
      const label = document.createElement('label'); label.className = 'option';
      const cb = document.createElement('input'); cb.type = 'checkbox'; cb.value = opt;
      cb.checked = state.filters[facet.key].has(opt);
      cb.addEventListener('change', () => {
        const set = state.filters[facet.key]; if (cb.checked) set.add(opt); else set.delete(opt); render(); drawActiveChips();
      });
      label.appendChild(cb);
      const span = document.createElement('span'); span.textContent = opt; label.appendChild(span);
      card.appendChild(label);
    }
    filtersEl.appendChild(card);
  }
  drawActiveChips();
}

function drawActiveChips() {
  const activeEl = document.getElementById('activeFilters'); activeEl.innerHTML = '';
  for (const f of FACETS) {
    for (const val of state.filters[f.key]) {
      const chip = document.createElement('span'); chip.className = 'chip'; chip.innerHTML = `${f.label}: ${val}`;
      const close = document.createElement('button'); close.setAttribute('aria-label', '移除筛选'); close.textContent = '×';
      close.addEventListener('click', () => { state.filters[f.key].delete(val); document.querySelectorAll('#filters input[type=checkbox]').forEach(cb => { if (cb.value === val) cb.checked = false; }); render(); drawActiveChips(); });
      chip.appendChild(close); activeEl.appendChild(chip);
    }
  }
}

function tagClass(t) {
  const low = normalize(t);
  if (low.includes('易消化') || low.includes('低刺激')) return 'tag good';
  if (low.includes('注意') || low.includes('慎用')) return 'tag warn';
  return 'tag';
}

function render() {
  const q = state.q;
  const list = RECIPES.filter(r => matchesFilters(r) && matchesQuery(r, q));
  const resultsEl = document.getElementById('results');
  const countEl = document.getElementById('resultCount');
  resultsEl.setAttribute('aria-busy', 'false');
  resultsEl.innerHTML = '';
  countEl.textContent = `${list.length} 条结果`;
  if (list.length === 0) {
    const empty = document.createElement('article'); empty.className = 'card';
    empty.innerHTML = `<h2>未找到匹配的食疗/食谱</h2><div class="meta">建议：减少关键词或更改筛选条件</div>`;
    resultsEl.appendChild(empty); return;
  }
  for (const r of list) {
    const card = document.createElement('article'); card.className = 'card';
    const title = document.createElement('h2'); title.innerHTML = highlight(r.name, q); card.appendChild(title);
    const tags = document.createElement('div'); tags.className = 'tags';
    const tagVals = [ ...(r.tags||[]), ...(r.constitution||[]), ...(r.season||[]), ...(r.stage||[]), r.stimulus ? `刺激:${r.stimulus}` : null, `易消化:${r.digestibility?'是':'否'}` ].filter(Boolean);
    for (const t of tagVals) { const span = document.createElement('span'); span.className = tagClass(t); span.innerHTML = highlight(t, q); tags.appendChild(span); }
    card.appendChild(tags);

    const meta1 = document.createElement('div'); meta1.className = 'meta'; meta1.innerHTML = `<strong>适应证：</strong>${highlight(r.indications, q)}`; card.appendChild(meta1);

    const funcTitle = document.createElement('div'); funcTitle.className = 'section-title'; funcTitle.textContent = '功效'; card.appendChild(funcTitle);
    const func = document.createElement('div'); func.className = 'method'; func.innerHTML = highlight(r.functions, q); card.appendChild(func);

    const methodTitle = document.createElement('div'); methodTitle.className = 'section-title'; methodTitle.textContent = '做法'; card.appendChild(methodTitle);
    const method = document.createElement('div'); method.className = 'method'; method.innerHTML = highlight(r.method, q); card.appendChild(method);

    const dosageTitle = document.createElement('div'); dosageTitle.className = 'section-title'; dosageTitle.textContent = '每日摄入建议'; card.appendChild(dosageTitle);
    const dosage = document.createElement('div'); dosage.className = 'dosage'; dosage.innerHTML = highlight(r.dosage, q); card.appendChild(dosage);

    const cautionTitle = document.createElement('div'); cautionTitle.className = 'section-title'; cautionTitle.textContent = '注意事项'; card.appendChild(cautionTitle);
    const caution = document.createElement('div'); caution.className = 'caution'; caution.innerHTML = highlight(r.caution, q); card.appendChild(caution);

    resultsEl.appendChild(card);
  }
}

function applyTheme() {
  document.documentElement.setAttribute('data-theme', state.theme);
}

async function main() {
  // 主题加载
  try { const t = localStorage.getItem('theme'); if (t) state.theme = t; } catch {}
  applyTheme();
  const toggle = document.getElementById('themeToggle');
  toggle.addEventListener('click', () => { state.theme = state.theme === 'light' ? 'dark' : 'light'; applyTheme(); try { localStorage.setItem('theme', state.theme); } catch {} });

  // 数据加载
  const resultsEl = document.getElementById('results');
  resultsEl.setAttribute('aria-busy', 'true');
  const res = await fetch(DATA_URL);
  RECIPES = await res.json();
  buildFilters(RECIPES);
  render();

  // 搜索输入 & 防抖
  const searchInput = document.getElementById('searchInput');
  const onSearch = debounce(() => { state.q = searchInput.value; render(); }, 200);
  searchInput.addEventListener('input', onSearch);

  // 清空
  document.getElementById('clearBtn').addEventListener('click', () => {
    state.q = ''; searchInput.value = '';
    for (const key of Object.keys(state.filters)) state.filters[key].clear();
    document.querySelectorAll('#filters input[type=checkbox]').forEach(cb => cb.checked = false);
    render(); drawActiveChips();
  });
}

main().catch(err => {
  const resultsEl = document.getElementById('results');
  const countEl = document.getElementById('resultCount');
  resultsEl.setAttribute('aria-busy', 'false');
  resultsEl.innerHTML = `<article class="card">数据加载失败：${String(err)}</article>`;
  countEl.textContent = '0 条结果';
});